#encoding:utf-8

from django import forms
from django.forms import ModelForm
from django.forms.extras import SelectDateWidget
from common.models import *
from common.forms import get_states, get_municipals
from countries_states.models import Country, State, Municipal
from models import *
from django.utils.translation import ugettext_lazy as _
from django.contrib.localflavor.us.forms import USPhoneNumberField
from datetime import date, timedelta, datetime

from userprofiles.forms import RegistrationForm


def get_company_areas():
    """
    Get company areas selections
    """
    choices = [('0', 'No aplica')]
    areas = Company_Area.objects.all()
    if areas.count() > 0:
        choices = [('-1', 'Seleccione...')]
        for area in areas:
            choices.append([area.id, area.name])
    return choices


def get_company_industries(area=None):
    """
    Get company industries selections based on the area parameter.
    """
    choices = [('0', 'No aplica')]
    if area:
        if type(area) == long:
            area = Company_Area.objects.get(pk= int(area))
        industries = area.company_industry_set.all()
        if industries.count() > 0:
            choices = [('-1', 'Seleccione...')]
            for industry in industries:
                choices.append([industry.id, industry.name])
    return choices


class CompanyForm(forms.ModelForm):
    company_name = forms.CharField(
        widget=forms.TextInput(attrs={'placeholder': _(u'Nombre de su empresa')}),
        max_length=100,
        error_messages={'required': _(u"Ingrese el nombre de su empresa")},
        label=_(u"Empresa")
    )
    company_area = forms.ChoiceField(
        choices=get_company_areas(),
        label=_(u'Sector')
    )
    company_industry = forms.ChoiceField(
        choices=get_company_industries(None),
        label=_(u'Giro')
    )
    company_phone = USPhoneNumberField(
        error_messages={'invalid': _(u"Ingrese un número telefónico valido")},
        widget=forms.TextInput(attrs={'placeholder': _(u'Número telefónico de su empresa')}),
    )
    url = forms.URLField(
        widget=forms.TextInput(attrs={'placeholder': _(u'Dirección Web de su empresa')}),
        max_length=200,
        label=_(u"Sitio Web"),
        required=False
    )
    logo = forms.ImageField(required=False)

    def __init__(self, *args, **kwargs):
        change_profile = False
        company_area_selected = kwargs.pop('company_area_selected', None)
        company_industry_selected = kwargs.pop('company_industry_selected', None)
        try:
            if kwargs.pop('change_profile'):
                change_profile = True
        except:
            None
        super(CompanyForm, self).__init__(*args, **kwargs)

        if change_profile:
            self.fields['company_area'].choices = get_company_areas()
            self.fields['company_industry'].choices = get_company_industries(company_area_selected)

        if self.is_bound:
            if company_industry_selected == -1:
                company_industry_selected = None
            self.fields['company_industry'].choices = get_company_industries(company_area_selected)

    def clean_company_area(self):
        area_id = int(self.cleaned_data.get('company_area'))
        if area_id < 0:
            raise forms.ValidationError(_(u'Seleccione una Industria'))
        if area_id == 0:
            return None
        try:
            area = self.cleaned_data.get('company_area')
            try:
                area = Company_Area.objects.get(pk = area_id)
            except:
                area = None
        except Company_Area.DoesNotExist:
            raise forms.ValidationError(_(u'El Area que seleccionó no es válida'))
        return area

    def clean_company_industry(self):
        industry_id = int(self.cleaned_data.get('company_industry'))
        if industry_id < 0:
            raise forms.ValidationError(_(u'Seleccione una Industria'))
        if industry_id == 0:
            return None
        try:
            # area_id = int(self.cleaned_data.get('company_area'))
            area = self.cleaned_data.get('company_area')
            try:
                industries = area.company_industry_set.all()
            except:
                industries = []
            choices = [0]
            for industry in industries:
                choices.append(industry.id)
            if industry_id not in choices:
                raise forms.ValidationError(_(u'Seleccione una Industria'))
            industry= Company_Industry.objects.get(pk = industry_id)
        except Company_Industry.DoesNotExist:
            raise forms.ValidationError(_(u'La Industria que seleccionó no es válida'))
        return industry

    def save(self, new_user, address, *args, **kwargs):
        new_company = Company.objects.create(
            user=new_user,
            company_name=self.cleaned_data['company_name'],
            url=self.cleaned_data['url'],
            company_area=self.cleaned_data['company_area'],
            company_industry=self.cleaned_data['company_industry'],
            phone=self.cleaned_data['company_phone'],
            logo=self.cleaned_data['logo'],
            address=address
        )

        return new_company

    def update(self, address, *args, **kwargs):
        company = super(CompanyForm, self).save(*args, **kwargs)

        company.company_name=self.cleaned_data['company_name']
        company.url=self.cleaned_data['url']
        company.company_area=self.cleaned_data['company_area']
        company.company_industry=self.cleaned_data['company_industry']
        company.phone=self.cleaned_data['company_phone']
        company.logo=self.cleaned_data['logo']
        company.address=address
        company.save()

        if hasattr(self, 'save_profile'):
            self.save_profile(company, *args, **kwargs)

        return company


    class Meta:
        model = Company
        exclude = ('user', 'address', 'area', 'industry', 'phone', 'logo')


def get_areas():
    choices = [('0', 'No aplica')]
    areas = Area.objects.all()
    if areas.count() > 0:
        choices = [('-1', 'Todas')]
        for area in areas:
            choices.append([area.id, area.name])
    return choices

def get_industries(area=None):
    """
    Get industries selections based on the area parameter.
    """
    choices = [('-1', 'Todas')]
    if area and area > 0:
        if type(area) != Area:
            print "no soy una area"
            area = Area.objects.get(pk=int(area))
        print type(area)
        industries = area.industry_set.all()
        if industries.count() > 0:
            for industry in industries:
                choices.append([industry.id, industry.name])
    return choices


def get_degrees():
    choices = []
    try:
        degrees = Degree.objects.all()
        for degree in degrees:
            choices.append([degree.id, degree.name])
    except:
        pass
    return choices


class VacancyForm(forms.ModelForm):
    initial_country = Country.objects.get(iso2_code__exact='MX')
    employment = forms.CharField(
        widget=forms.TextInput(attrs={'placeholder': _(u'Puesto')}),
        max_length=120,
        min_length=10,
        error_messages={'required': _(u"Ingrese el puesto requerido")},
        label=_(u"Puesto")
    )
    description = forms.CharField(
        widget=forms.Textarea(attrs={'placeholder': _(u'Descripción')}),
        min_length=100,
        error_messages={'required': _(u"Ingrese la descripción del puesto")},
        label=_(u"Descripción")
    )
    employmentType = forms.ModelChoiceField(
        queryset=Employment_Type.objects.all(),
        required=True,
        label=_(u'Tipo de contratación'),
        initial=Employment_Type.objects.get(id=1)
    )
    salaryType = forms.ModelChoiceField(
        queryset=Salary_Type.objects.all(),
        required=True,
        label=_(u'Salario'),
        initial=Salary_Type.objects.get(codename__exact='unspecified')
    )
    salary = forms.IntegerField(
        widget=forms.TextInput(attrs={'placeholder': _(u'Sueldo')}),
        label=_(u"Especifique el sueldo"),
        required=False,
        error_messages={
            'invalid': _(u'Introduzca un número')
        }
    )
    state = forms.ChoiceField(
        choices=get_states(initial_country),
        label=_(u'Estado'),
        error_messages={
            'required': _(u"Seleccione un Estado"),
            'blank': _('Seleccione un Estado y un Municipio"'),
            'invalid_choice': _('El Estado no es válido')},
    )
    municipal = forms.ChoiceField(
        choices=get_municipals(None),
        label=_(u'Municipio'),
        error_messages={
            'required': _(u"Seleccione un Estado y un Municipio"),
            'blank': _('Seleccione un Estado y un Municipio"'),
            'invalid_choice': _('Este Municipio no es válido')},
    )
    gender = forms.ModelChoiceField(
        queryset=Gender.objects.all(),
        required=True,
        label=_(u'Género'),
        initial=Gender.objects.get(id=1)
    )
    degree = forms.ModelChoiceField(
        queryset=Degree.objects.all(),
        required=True,
        label=_(u'Nivel de educación'),
        initial=Degree.objects.get(id=1)
    )
    area = forms.ChoiceField(
        choices=get_areas(),
        label=_(u'Area'),
    )
    industry = forms.ChoiceField(
        choices=get_industries(area=0),
        label=_(u'Sector')
    )
    employmentExperience = forms.ModelChoiceField(
        queryset=Employment_Experience.objects.all(),
        required=True,
        label=_(u'Experiencia requerida'),
        initial=Employment_Type.objects.get(id=1)
    )
    pub_after = forms.BooleanField(widget=forms.CheckboxInput(),
                                   required=False,
                                   label=_('¿Publicar a fecha futura?'),
                                   initial=False)
    pub_date = forms.DateField(widget=SelectDateWidget(years=('2013', '2014')), initial=date.today, required=False)
    #### degree = forms.MultipleChoiceField(required=False,
    ####    widget=forms.CheckboxSelectMultiple, choices=get_degrees())
    min_age = forms.ChoiceField(
        choices=get_ages(),
        required=True,
        label=_(u'Edad mínima'),
        initial='0'
    )
    max_age = forms.ChoiceField(
        choices=get_ages(),
        required=True,
        label=_(u'Edad máxima'),
        initial='0'
    )
    def __init__(self, vacancy=None, *args, **kwargs):
        change_vacancy = False
        state_selected = kwargs.pop('state_selected', None)
        area_selected = kwargs.pop('area_selected', None)
        try:
            if kwargs.pop('change_vacancy'):
                change_vacancy = True
        except:
            pass
        super(VacancyForm, self).__init__(*args, **kwargs)

        if change_vacancy:
            now = date
            if now > vacancy.pub_date and not vacancy.pub_after:
                del self.fields['pub_after']
                del self.fields['pub_date']
            self.fields['state'].choices = get_states(self.initial_country)
            self.fields['municipal'].choices = get_municipals(vacancy.state.pk)

        if self.is_bound:
            self.fields['industry'].choices = get_industries(area_selected)
            self.fields['municipal'].choices = get_municipals(state_selected)

    def clean_employmentType(self):
        if not self.cleaned_data.get('employmentType'):
            raise forms.ValidationError(_(u'Seleccione el tipo de contratacion'))
        return self.cleaned_data['employmentType']

    def clean_area(self):
        area_id = int(self.cleaned_data.get('area'))
        if area_id == -1:
            return None
        try:
            try:
                areas = get_areas()
            except:
                pass
            choices = []
            for area in areas:
                choices.append(int(area[0]))
            if area_id not in choices:
                raise forms.ValidationError(_(u'Area inválida 1'))
            if area_id > 0:
                area = Area.objects.get(pk = area_id)
        except Area.DoesNotExist:
            raise forms.ValidationError(_(u'Area inválida 2'))
        return area

    def clean_industry(self):
        area = self.cleaned_data.get('area')
        industry_id = int(self.cleaned_data.get('industry'))
        if not area:
            return None
        if industry_id == -1:
            return None
        try:
            choices = []
            try:
                industries = area.industry_set.all()
                for industry in industries:
                    choices.append(industry.id)
            except:
                raise forms.ValidationError(_(u'La Industria que seleccionó no es válida'))
            if industry_id not in choices:
                raise forms.ValidationError(_(u'La Industria que seleccionó no es válida'))
                # state = State.objects.get(id=state)
            industry = Industry.objects.get(pk=industry_id)
            print industry
        except Industry.DoesNotExist:
            raise forms.ValidationError(_(u'La Industria que seleccionó no es válida'))
        return industry

    def clean_pub_date(self):
        pub_after = self.cleaned_data['pub_after']
        pub_date = date.today()
        if pub_after:
            if not self.cleaned_data.get('pub_date'):
                raise forms.ValidationError(_(u'Seleccione una fecha'))
            pub_date = self.cleaned_data.get('pub_date')
            if pub_date <= date.today():
                raise forms.ValidationError(_(u'Seleccione una fecha a futuro'))
        return pub_date

    def clean_state(self):
        state_id = int(self.cleaned_data.get('state'))
        if state_id < 0:
            raise forms.ValidationError(_(u'Seleccione un Estado'))
        try:
            country = self.initial_country
            try:
                states = country.state_set.filter(active=True)
            except:
                states = []
            choices = [0]
            for state in states:
                choices.append(state.id)
            if state_id not in choices:
                raise forms.ValidationError(_(u'El Estado que seleccionó no es válido'))
            state = State.objects.get(pk = state_id)
        except State.DoesNotExist:
            raise forms.ValidationError(_(u'El Estado que seleccionó no es válido'))
        return state

    def clean_municipal(self):
        municipal_id = int(self.cleaned_data.get('municipal'))
        if municipal_id < 0:
            raise forms.ValidationError(_(u'Seleccione un Municipio'))
        if municipal_id == 0:
            return None
        try:
            choices = [0]
            try:
                state = self.cleaned_data.get('state')
                state_id = state.pk
                state = State.objects.get(id=state_id)
                municipals = state.municipal_set.all()
                for municipal in municipals:
                    choices.append(municipal.id)
            except:
                return None
            if municipal_id not in choices:
                raise forms.ValidationError(_(u'Seleccione un Municipio 2'))
            municipal = Municipal.objects.get(pk = municipal_id)
        except Municipal.DoesNotExist:
            raise forms.ValidationError(_(u'El Municipio que seleccionó no es válido'))
        return municipal

    def clean_salaryType(self):
        salary_type_id = int(None if self.data['salaryType'] is None else self.data['salaryType'])
        try:
            salaryType = Salary_Type.objects.get(pk=salary_type_id)
        except:
            raise forms.ValidationError(_(u'El tipo de salario seleccionado no es válido'))
        return salaryType

    def clean_salary(self):
        salary_type_id = int(None if self.data['salaryType'] is None else self.data['salaryType'])
        try:
            salaryType = Salary_Type.objects.get(pk=salary_type_id)
        except:
            raise forms.ValidationError(_(u'El tipo de salario seleccionado no es válido'))
        if salaryType.codename == 'fixed' and not self.data['salary'] or self.data['salary'] == 0:
            raise forms.ValidationError(_(u'Debe ingresar un monto'))
        elif salaryType.codename != 'fixed' and self.data['salary'] != '' != 0:
            raise forms.ValidationError(_(u'No puede ingresar un sueldo ya que el salario seleccionado no es Fijo'))
        # try:
        salary = int(self.cleaned_data.get('salary'))
        if salary <= 60:
            raise forms.ValidationError(_(u'Debe ingresar una cantidad válida mayor a 60'))
        elif salary >= 999999:
            raise forms.ValidationError(_(u'Debe ingresar una cantidad válida menor a 999999'))
        # except:
        #     return None
        return salary

    def clean_min_age(self):
        min_age = int(0 if self.cleaned_data.get('min_age') is None else self.cleaned_data.get('min_age'))
        max_age = int(0 if self.data['max_age'] is None else self.data['max_age'])
        if min_age == 0 and max_age == 0:
            return None
        # except:
        if min_age == 0 and max_age != 0:
            raise forms.ValidationError(_(u'Elija una edad mínima'))
        if min_age < 15 or min_age > 65:
                raise forms.ValidationError(_(u'Elija una edad dentro del rango de 18 a 65 años'))
        if min_age > max_age != 0:
            raise forms.ValidationError(_(u'La edad mínima es mayor a la edad máxima, por favor seleccione edades válidas'))
        return min_age

    def clean_max_age(self):
        min_age = int(0 if self.data['min_age'] is None else self.data['min_age'])
        max_age = int(0 if self.cleaned_data.get('max_age') is None else self.cleaned_data.get('max_age'))
        if min_age == 0 and max_age == 0:
            return None
        if min_age != 0 and max_age == 0:
            raise forms.ValidationError(_(u'Elija una edad máxima'))
        if max_age < 15 or max_age > 65:
                raise forms.ValidationError(_(u'Elija una edad dentro del rango de 18 a 65 años'))
        return max_age

    def save(self, company, user):
        # TODO: Cambiar active dependiendo la fecha y la fecha de fin dependiendo el tipo de anuncio
        if not self.cleaned_data['pub_after']:
            status = VacancyStatus.objects.get(codename__exact='active')
        else:
            status = VacancyStatus.objects.get(codename__exact='programmed')
        new_vacancy = Vacancy.objects.create(
            company=company,
            user=user,
            status=status,
            employment=self.cleaned_data['employment'],
            description=self.cleaned_data['description'],
            state=self.cleaned_data['state'],
            municipal=self.cleaned_data['municipal'],
            area=self.cleaned_data['area'],
            industry=self.cleaned_data['industry'],
            gender=self.cleaned_data['gender'],
            employmentType=self.cleaned_data['employmentType'],
            employmentExperience=self.cleaned_data['employmentExperience'],
            degree=self.cleaned_data['degree'],
            min_age=self.cleaned_data['min_age'],
            max_age=self.cleaned_data['max_age'],
            salaryType=self.cleaned_data['salaryType'],
            salary=self.cleaned_data['salary'],
            pub_after=self.cleaned_data['pub_after'],
            pub_date=self.cleaned_data['pub_date'],
            end_date=self.cleaned_data['pub_date']+timedelta(30),
        )

        return new_vacancy

    def update(self, vacancy, *args, **kwargs):

        if not self.cleaned_data['pub_after']:
            status = VacancyStatus.objects.get(codename__exact='active')
        else:
            status = VacancyStatus.objects.get(codename__exact='programmed')
        now = date.today()
        vacancy.status = status
        vacancy.employment = self.cleaned_data['employment']
        vacancy.description = self.cleaned_data['description']
        vacancy.state = self.cleaned_data['state']
        vacancy.municipal = self.cleaned_data['municipal']
        vacancy.area = self.cleaned_data['area']
        vacancy.industry = self.cleaned_data['industry']
        vacancy.gender = self.cleaned_data['gender']
        vacancy.employmentType = self.cleaned_data['employmentType']
        vacancy.employmentExperience=self.cleaned_data['employmentExperience']
        vacancy.degree = self.cleaned_data['degree']
        vacancy.min_age = self.cleaned_data['min_age']
        vacancy.max_age = self.cleaned_data['max_age']
        vacancy.salaryType=self.cleaned_data['salaryType']
        vacancy.salary = self.cleaned_data['salary']
        if now < vacancy.pub_date.date() and vacancy.pub_after:
            vacancy.pub_after = self.cleaned_data['pub_after']
            vacancy.pub_date = self.cleaned_data['pub_date']
            vacancy.end_date = self.cleaned_data['pub_date']+timedelta(30)

        vacancy.save()

        return vacancy

    class Meta:
        model = Vacancy
        exclude = ('company', 'user', 'active', 'add_date', 'end_date', 'last_modified', 'status')
